<?php

require_once('HproseCommon.php');
require_once('HproseIO.php');
class HproseHttpServer {
private $functions;
private $IIIIIIII1l1I;
private $IIIIIIII1l1l;
private $IIIIIIII1l11;
private $IIIIIIII11II;
private $IIIIIIII11Il;
private $IIIIIIII11I1;
private $IIIIIIII11lI;
private $IIIIIIII11ll;
private $IIIIIIII11l1;
private $IIIIIIII111I;
private $IIIIIIII111l;
public $onBeforeInvoke;
public $onAfterInvoke;
public $onSendHeader;
public $onSendError;
public function __construct() {
$this->functions = array();
$this->IIIIIIII1l1I = array();
$this->IIIIIIII1l1l = array();
$this->IIIIIIII1l11 = false;
$this->IIIIIIII11II = false;
$this->IIIIIIII11Il = false;
$this->IIIIIIII11I1 = true;
if (!isset($IIIIIIII1111)) $IIIIIIII1111 = file_get_contents("php://input");
$this->IIIIIIII11lI = new HproseStringStream($IIIIIIII1111);
$this->IIIIIIII11l1 = new HproseReader($this->IIIIIIII11lI);
$this->IIIIIIII11ll = new HproseFileStream(fopen('php://output','wb'));
$this->IIIIIIII111I = new HproseWriter($this->IIIIIIII11ll);
$this->onBeforeInvoke = NULL;
$this->onAfterInvoke = NULL;
$this->onSendHeader = NULL;
$this->onSendError = NULL;
set_error_handler(array(&$this,'__errorHandler'));
ob_start(array(&$this,"__fatalErrorHandler"));
ob_implicit_flush(0);
}
public function __fatalErrorHandler($data) {
$s = HproseTags::TagEnd;
if (preg_match('/<b>.*? error<\/b>:(.*?)<br/',$data,$IIIIIIIlIIll)) {
if ($this->IIIIIIII1l11) {
$IIIIIIII111l = preg_replace('/<.*?>/','',$IIIIIIIlIIll[1]);
}
else {
$IIIIIIII111l = preg_replace('/ in <b>.*<\/b>$/','',$IIIIIIIlIIll[1]);
}
$s = HproseTags::TagError .
HproseFormatter::serialize(trim($IIIIIIII111l)) .
HproseTags::TagEnd;
}
return $s;
}
public function __errorHandler($errno,$errstr,$errfile,$errline) {
if ($this->IIIIIIII1l11) {
$errstr .= " in $errfile on line $errline";
}
if (($errno == E_ERROR) or ($errno == E_CORE_ERROR) or
($errno == E_COMPILE_ERROR) or ($errno == E_USER_ERROR)) {
$this->IIIIIIII111l = $errstr;
$this->sendError();
}
return true;
}
private function sendHeader() {
if (!is_null($this->onSendHeader)) {
call_user_func($this->onSendHeader);
}
header("Content-Type: text/plain");
if ($this->IIIIIIII11Il) {
header('P3P: CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi '.
'CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL '.
'UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"');
}
if ($this->IIIIIIII11II) {
$IIIIIIIlIlI1 = $_SERVER['HTTP_ORIGIN'];
if ($IIIIIIIlIlI1 &&$IIIIIIIlIlI1 != "null") {
header("Access-Control-Allow-Origin: ".$IIIIIIIlIlI1);
header("Access-Control-Allow-Credentials: true");
}
else {
header('Access-Control-Allow-Origin: *');
}
}
}
private function sendError() {
if (!is_null($this->onSendError)) {
call_user_func($this->onSendError,$this->IIIIIIII111l);
}
ob_end_clean();
$this->IIIIIIII11ll->write(HproseTags::TagError);
$this->IIIIIIII111I->reset();
$this->IIIIIIII111I->writeString($this->IIIIIIII111l,false);
$this->IIIIIIII11ll->write(HproseTags::TagEnd);
}
private function call($function,&$args,$byref) {
if ($byref) {
$arguments = array();
for ($IIIIIIII1lll = 0;$IIIIIIII1lll <count($args);$IIIIIIII1lll++) {
$arguments[$IIIIIIII1lll] = &$args[$IIIIIIII1lll];
}
}
else {
$arguments = $args;
}
return call_user_func_array($function,$arguments);
}
private function doInvoke() {
do {
$this->IIIIIIII11l1->reset();
$functionName = $this->IIIIIIII11l1->readString();
$IIIIIIIlIl11 = strtolower($functionName);
$resultMode = HproseResultMode::Normal;
$IIIIIIIlI1II = array();
$byref = false;
$tag = $this->IIIIIIII11l1->checkTags(array(HproseTags::TagList,
HproseTags::TagEnd,
HproseTags::TagCall));
if ($tag == HproseTags::TagList) {
$this->IIIIIIII11l1->reset();
$IIIIIIIlI1II = &$this->IIIIIIII11l1->readList(false);
$tag = $this->IIIIIIII11l1->checkTags(array(HproseTags::TagTrue,
HproseTags::TagEnd,
HproseTags::TagCall));
if ($tag == HproseTags::TagTrue) {
$byref = true;
$tag = $this->IIIIIIII11l1->checkTags(array(HproseTags::TagEnd,
HproseTags::TagCall));
}
}
if (!is_null($this->onBeforeInvoke)) {
call_user_func($this->onBeforeInvoke,$functionName,$IIIIIIIlI1II,$byref);
}
if (array_key_exists($IIIIIIIlIl11,$this->functions)) {
$function = $this->functions[$IIIIIIIlIl11];
$resultMode = $this->IIIIIIII1l1l[$IIIIIIIlIl11];
$IIIIIIIlI1I1 = $this->call($function,$IIIIIIIlI1II,$byref);
}
else if (array_key_exists('*',$this->functions)) {
$resultMode = $this->IIIIIIII1l1l['*'];
$arguments = array($functionName,&$IIIIIIIlI1II);
$IIIIIIIlI1I1 = call_user_func_array($this->functions['*'],$arguments);
}
else {
throw new HproseException("Can't find this function ".$functionName ."().");
}
if (!is_null($this->onAfterInvoke)) {
call_user_func($this->onAfterInvoke,$functionName,$IIIIIIIlI1II,$byref,$IIIIIIIlI1I1);
}
if ($resultMode == HproseResultMode::RawWithEndTag) {
$this->IIIIIIII11ll->write($IIIIIIIlI1I1);
return;
}
else if ($resultMode == HproseResultMode::Raw) {
$this->IIIIIIII11ll->write($IIIIIIIlI1I1);
}
else {
$this->IIIIIIII11ll->write(HproseTags::TagResult);
if ($resultMode == HproseResultMode::Serialized) {
$this->IIIIIIII11ll->write($IIIIIIIlI1I1);
}
else {
$this->IIIIIIII111I->reset();
$this->IIIIIIII111I->serialize($IIIIIIIlI1I1);
}
if ($byref) {
$this->IIIIIIII11ll->write(HproseTags::TagArgument);
$this->IIIIIIII111I->reset();
$this->IIIIIIII111I->writeList($IIIIIIIlI1II,false);
}
}
}while ($tag == HproseTags::TagCall);
$this->IIIIIIII11ll->write(HproseTags::TagEnd);
}
private function doFunctionList() {
$functions = array_values($this->IIIIIIII1l1I);
$this->IIIIIIII11ll->write(HproseTags::TagFunctions);
$this->IIIIIIII111I->writeList($functions,false);
$this->IIIIIIII11ll->write(HproseTags::TagEnd);
}
private function getDeclaredOnlyMethods($class) {
$IIIIIIIlI11I = get_class_methods($class);
if ($IIIIIIIlI11l = get_parent_class($class)) {
$IIIIIIIlI111 = get_class_methods($IIIIIIIlI11l);
$IIIIIIIlI1I1 = array_diff($IIIIIIIlI11I,$IIIIIIIlI111);
}
else {
$IIIIIIIlI1I1 = $IIIIIIIlI11I;
}
return $IIIIIIIlI1I1;
}
public function addMissingFunction($function,$resultMode = HproseResultMode::Normal) {
$this->addFunction($function,'*',$resultMode);
}
public function addFunction($function,$alias = NULL,$resultMode = HproseResultMode::Normal) {
if (is_callable($function)) {
if (is_null($alias)) {
if (is_string($function)) {
$alias = $function;
}
else {
$alias = $function[1];
}
}
if (is_string($alias)) {
$IIIIIIIlIl11 = strtolower($alias);
$this->functions[$IIIIIIIlIl11] = $function;
$this->IIIIIIII1l1I[$IIIIIIIlIl11] = $alias;
$this->IIIIIIII1l1l[$IIIIIIIlIl11] = $resultMode;
}
else {
throw new HproseException('Argument alias is not a string');
}
}
else {
throw new HproseException('Argument function is not a callable variable');
}
}
public function addFunctions($functions,$aliases = NULL,$resultMode = HproseResultMode::Normal) {
$IIIIIIIllIll = is_null($aliases);
$IIIIIIIllIl1 = count($functions);
if (!$IIIIIIIllIll &&$IIIIIIIllIl1 != count($aliases)) {
throw new HproseException('The count of functions is not matched with aliases');
}
for ($IIIIIIII1lll = 0;$IIIIIIII1lll <$IIIIIIIllIl1;$IIIIIIII1lll++) {
$function = $functions[$IIIIIIII1lll];
if ($IIIIIIIllIll) {
$this->addFunction($function,NULL,$resultMode);
}
else {
$this->addFunction($function,$aliases[$IIIIIIII1lll],$resultMode);
}
}
}
public function addMethod($methodname,$belongto,$alias = NULL,$resultMode = HproseResultMode::Normal) {
if ($alias == NULL) {
$alias = $methodname;
}
if (is_string($belongto)) {
$this->addFunction(array($belongto,$methodname),$alias,$resultMode);
}
else {
$this->addFunction(array(&$belongto,$methodname),$alias,$resultMode);
}
}
public function addMethods($methods,$belongto,$aliases = NULL,$resultMode = HproseResultMode::Normal) {
$IIIIIIIllIll = is_null($aliases);
$IIIIIIIllIl1 = count($methods);
if (is_string($aliases)) {
$aliasPrefix = $aliases;
$aliases = array();
foreach ($methods as $name) {
$aliases[] = $aliasPrefix .'_'.$name;
}
}
if (!$IIIIIIIllIll &&$IIIIIIIllIl1 != count($aliases)) {
throw new HproseException('The count of methods is not matched with aliases');
}
for ($IIIIIIII1lll = 0;$IIIIIIII1lll <$IIIIIIIllIl1;$IIIIIIII1lll++) {
$IIIIIIIllI11 = $methods[$IIIIIIII1lll];
if (is_string($belongto)) {
$function = array($belongto,$IIIIIIIllI11);
}
else {
$function = array(&$belongto,$IIIIIIIllI11);
}
if ($IIIIIIIllIll) {
$this->addFunction($function,$IIIIIIIllI11,$resultMode);
}
else {
$this->addFunction($function,$aliases[$IIIIIIII1lll],$resultMode);
}
}
}
public function addInstanceMethods($object,$class = NULL,$aliasPrefix = NULL,$resultMode = HproseResultMode::Normal) {
if (is_null($class)) $class = get_class($object);
$this->addMethods($this->getDeclaredOnlyMethods($class),$object,$aliasPrefix,$resultMode);
}
public function addClassMethods($class,$execclass = NULL,$aliasPrefix = NULL,$resultMode = HproseResultMode::Normal) {
if (is_null($execclass)) $execclass = $class;
$this->addMethods($this->getDeclaredOnlyMethods($class),$execclass,$aliasPrefix,$resultMode);
}
public function add() {
$IIIIIIIIIIIl = func_num_args();
$args = func_get_args();
switch ($IIIIIIIIIIIl) {
case 1: {
if (is_callable($args[0])) {
return $this->addFunction($args[0]);
}
elseif (is_array($args[0])) {
return $this->addFunctions($args[0]);
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0]);
}
elseif (is_string($args[0])) {
return $this->addClassMethods($args[0]);
}
break;
}
case 2: {
if (is_callable($args[0]) &&is_string($args[1])) {
return $this->addFunction($args[0],$args[1]);
}
elseif (is_string($args[0])) {
if (is_string($args[1]) &&!is_callable(array($args[1],$args[0]))) {
if (class_exists($args[1])) {
return $this->addClassMethods($args[0],$args[1]);
}
else {
return $this->addClassMethods($args[0],NULL,$args[1]);
}
}
return $this->addMethod($args[0],$args[1]);
}
elseif (is_array($args[0])) {
if (is_array($args[1])) {
return $this->addFunctions($args[0],$args[1]);
}
else {
return $this->addMethods($args[0],$args[1]);
}
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0],$args[1]);
}
break;
}
case 3: {
if (is_callable($args[0]) &&is_null($args[1]) &&is_string($args[2])) {
return $this->addFunction($args[0],$args[2]);
}
elseif (is_string($args[0]) &&is_string($args[2])) {
if (is_string($args[1]) &&!is_callable(array($args[0],$args[1]))) {
return $this->addClassMethods($args[0],$args[1],$args[2]);
}
else {
return $this->addMethod($args[0],$args[1],$args[2]);
}
}
elseif (is_array($args[0])) {
if (is_null($args[1]) &&is_array($args[2])) {
return $this->addFunctions($args[0],$args[2]);
}
else {
return $this->addMethods($args[0],$args[1],$args[2]);
}
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0],$args[1],$args[2]);
}
break;
}
throw new HproseException('Wrong arguments');
}
}
public function isDebugEnabled() {
return $this->IIIIIIII1l11;
}
public function setDebugEnabled($enable = true) {
$this->IIIIIIII1l11 = $enable;
}
public function isCrossDomainEnabled() {
return $this->IIIIIIII11II;
}
public function setCrossDomainEnabled($enable = true) {
$this->IIIIIIII11II = $enable;
}
public function isP3PEnabled() {
return $this->IIIIIIII11Il;
}
public function setP3PEnabled($enable = true) {
$this->IIIIIIII11Il = $enable;
}
public function isGetEnabled() {
return $this->IIIIIIII11I1;
}
public function setGetEnabled($enable = true) {
$this->IIIIIIII11I1 = $enable;
}
public function handle() {
ob_end_clean();
$this->sendHeader();
if (($_SERVER['REQUEST_METHOD'] == 'GET') and $this->IIIIIIII11I1) {
return $this->doFunctionList();
}
try {
$IIIIIIIll1ll = array(HproseTags::TagCall,HproseTags::TagEnd);
$tag = $this->IIIIIIII11l1->checkTags($IIIIIIIll1ll);
switch ($tag) {
case HproseTags::TagCall: return $this->doInvoke();
case HproseTags::TagEnd: return $this->doFunctionList();
}
}
catch (Exception $IIIIIIIll1l1) {
$this->IIIIIIII111l = $IIIIIIIll1l1->getMessage();
if ($this->IIIIIIII1l11) {
$this->IIIIIIII111l .= "\nfile: ".$IIIIIIIll1l1->getFile() .
"\nline: ".$IIIIIIIll1l1->getLine() .
"\ntrace: ".$IIIIIIIll1l1->getTraceAsString();
}
$this->sendError();
}
$this->IIIIIIII11lI->close();
$this->IIIIIIII11ll->close();
}
public function start() {
$this->handle();
}
}
?>
